# _*_ coding:utf-8 _*_
# @Time  : 2022-02-16
# @Author: zizle

import datetime
from fastapi import APIRouter, Header, Body, Query
from pydantic import BaseModel, ValidationError, validator, conint, datetime_parse

from hutool import security
from v1_all_api import constant
from v1_all_api.all_response import AllResponse
from v1_all_api.all_utils import datetime_utils
from db import FAConnection

user_variety_api = APIRouter()


# 品种的空间归属过滤器
def variety_space_filter(space, item):
    return space in item['spaces'].split(',')


# 品种的空间名称处理器
def variety_zh_name_handler(item):
    item['variety_long_name'] = f'{item["variety_name"]}({item["variety_en"]})'
    item['spaces_zh'] = ','.join([constant.VARIETY_SPACES.get(s, '') for s in item['spaces'].split(',')])
    return item


class UserVarietyItem(BaseModel):
    user_id: conint(ge=1)
    variety_en: str
    name_space: str
    expire: datetime_parse.date

    @validator('name_space')
    def validate_name_space(cls, value):
        if value not in constant.VARIETY_SPACES.keys():
            raise ValidationError('品种空间错误')
        return value


@user_variety_api.post('/userVarietyAccesses/')  # 将品种权限分配给用户
def create_user_variety(ruizy_token: str = Header(...), user_variety: UserVarietyItem = Body(...)):
    person = security.decrypt_access_token(ruizy_token)
    if not person:
        return AllResponse.no_authorization()
    if not security.operator_is_super_admin(person):
        return AllResponse.forbidden_error()

    with FAConnection() as cursor:
        cursor.execute('SELECT id,role_code FROM ruizy_user WHERE id=%s LIMIT 1;', [user_variety.user_id])
        o_user = cursor.fetchone()
        if not o_user:
            return AllResponse.server_no_content(msg='操作用户不存在!')
        if o_user['role_code'] in [constant.ADMIN_ROLE_CODE, constant.MANAGE_ROLE_CODE, constant.SPECIAL_ANALYST]:
            return AllResponse.no_do_anything(msg='此用户已经有全品种权限!')
        cursor.execute('SELECT id FROM ruizy_user_variety WHERE user_id=%s AND variety_en=%s AND name_space=%s AND expire>=%s LIMIT 1;',
                       [user_variety.user_id, constant.SPACE_VARIETY_ALL, user_variety.name_space, datetime_utils.today(f='%Y-%m-%d')])
        is_space_all = cursor.fetchone()

        if is_space_all and user_variety.variety_en != constant.SPACE_VARIETY_ALL:
            return AllResponse.no_do_anything(msg='改用户已经有该模块的全品种权限!')

        # 权限入库
        cursor.execute('SELECT id FROM ruizy_user_variety WHERE user_id=%s AND variety_en=%s AND name_space=%s;',
                       [user_variety.user_id, user_variety.variety_en, user_variety.name_space])
        o_user_space_v = cursor.fetchone()
        if o_user_space_v:
            cursor.execute('UPDATE ruizy_user_variety SET expire=%s WHERE user_id=%s AND variety_en=%s AND name_space=%s;',
                           [user_variety.expire, user_variety.user_id, user_variety.variety_en, user_variety.name_space])
        else:
            cursor.execute('INSERT INTO ruizy_user_variety (user_id,variety_en,name_space,expire) VALUES (%s,%s,%s,%s);',
                           [user_variety.user_id, user_variety.variety_en, user_variety.name_space, user_variety.expire])
    return AllResponse.operate_successfully(msg='设置品种权限成功!')


# 获取用户有权限的品种(用户获取)
@user_variety_api.get('/userVariety/')
def user_variety_accesses_only(ruizy_token: str = Header(...), space: str = Query(None)):
    now_day = datetime.datetime.today().strftime('%Y-%m-%d')

    def filter_no_permission(item):
        if space:
            return item['expire'] and item['expire'].strftime('%Y-%m-%d') >= now_day and item['name_space'] == space
        else:
            return item['expire'] and item['expire'].strftime('%Y-%m-%d') >= now_day

    token_payload = security.decrypt_access_token(ruizy_token)
    if not token_payload:
        return AllResponse.no_authorization()
    # 查询品种
    query_sql = """
        SELECT a.variety_en,a.spaces,a.variety_name,a.group_name,a.exchange_name,a.is_real,a.price_unit,a.hand_unit,
            a.hand_amount,a.fund,a.bail_rate,
            b.expire,b.name_space 
        FROM ruizy_variety As a 
        LEFT JOIN ruizy_user_variety As b ON a.variety_en=b.variety_en AND b.user_id=%s AND b.variety_en<>%s AND b.expire>=CURDATE()
        WHERE a.is_active=1;
    """
    query_prm = [token_payload['uid'], constant.SPACE_VARIETY_ALL]
    all_variety_sql = """
        SELECT id FROM ruizy_user_variety WHERE user_id=%s AND variety_en=%s AND name_space=%s AND expire>=%s LIMIT 1;
    """
    all_variety_prm = [token_payload['uid'], constant.SPACE_VARIETY_ALL, space, now_day]
    with FAConnection() as cursor:
        cursor.execute(query_sql, query_prm)
        records = list(cursor.fetchall())
        # 查询本模块此人是不是全品种
        is_space_all = {}
        if space:
            cursor.execute(all_variety_sql, all_variety_prm)
            is_space_all = cursor.fetchone()
    if space:  # 过滤掉不属于本空间的品种记录
        records = list(filter(lambda x: space in x['spaces'].split(','), records))
        if not is_space_all:  # 不是全品种权限
            # 提取b.name_space=None或者等于本查询空间的
            records = list(filter(lambda x: not x['name_space'] or x['name_space'] == space, records))
    else:
        # 根据variety_en去重
        fina_list = []
        v_list = []
        for v in records:
            if v['variety_en'] in v_list:
                continue
            else:
                v_list.append(v['variety_en'])
                fina_list.append(v)
        records = fina_list

    records = list(map(variety_zh_name_handler, records))
    records.sort(key=lambda x: x['variety_en'])
    # 根据用户身份过滤数据
    # 超级管理员、特别管理员、特别研究员所有品种。
    if token_payload['role_code'] in [constant.ADMIN_ROLE_CODE, constant.MANAGE_ROLE_CODE, constant.SPECIAL_ANALYST]:
        return AllResponse.operate_successfully(data=records)
    if space and is_space_all:  # 该模块全品种
        # print('返回全品种', space)
        # for r in records:
        #     print(r)
        return AllResponse.operate_successfully(data=records)
    # 过滤无权限的品种
    records = list(filter(filter_no_permission, records))
    return AllResponse.operate_successfully(data=records)


# 获取用户的权限品种(后台管理使用)
@user_variety_api.get('/userVarietyAccesses/')
def get_user_variety(ruizy_token: str = Header(...), uid: int = Query(..., ge=1)):
    person = security.decrypt_access_token(ruizy_token)
    if not person:
        return AllResponse.no_authorization()
    if not security.operator_is_super_admin(person):
        return AllResponse.forbidden_error()

    # 查询用户的品种权限
    sql = """
        SELECT v.id,v.variety_en,v.variety_name,v.group_name,v.exchange_name,v.spaces,
            uv.expire,uv.name_space   
        FROM ruizy_variety As v 
        LEFT JOIN ruizy_user_variety As uv ON v.variety_en=uv.variety_en AND uv.user_id=%s 
        ORDER BY v.variety_en,uv.name_space;
    """

    with FAConnection() as cursor:
        cursor.execute('SELECT id,ruizy_code,nickname,phone,expire,role,is_analyst,expire,admin_name FROM ruizy_user WHERE id=%s;',
                       [uid])
        user_obj = cursor.fetchone()
        if not user_obj:
            return AllResponse.server_no_content(msg='查询的用户不存在！')
        # 查询用户的品种权限
        cursor.execute(sql, [uid])
        records = list(cursor.fetchall())
        # 查询用户的全品种权限的模块
        cursor.execute('SELECT id,name_space FROM ruizy_user_variety WHERE variety_en=%s AND user_id=%s AND expire>=%s;',
                       [constant.SPACE_VARIETY_ALL, uid, datetime_utils.today(f='%Y-%m-%d')])
        spaces = list(cursor.fetchall())

    variety_data = []
    today = datetime.datetime.today().strftime('%Y-%m-%d')
    for row in records:
        exist_index = -1
        accesses_zh = []  # 有权限的空间中文说明
        for i, v in enumerate(variety_data):
            if v['variety_en'] == row['variety_en']:
                exist_index = i
                break
        if exist_index > -1 and row['expire']:  # 存在,不会出现存在而没有expire的情况
            accesses_zh = variety_data[exist_index]['accesses_zh'].split(',')
            for ac in variety_data[exist_index]['accesses']:
                if ac['name_space'] == row['name_space']:
                    ac['expire'] = row['expire']
                    ac['accessible'] = row['expire'].strftime('%Y-%m-%d') >= today
                    if ac['accessible']:
                        accesses_zh.append(constant.VARIETY_SPACES.get(ac['name_space']))
            variety_data[exist_index]['accesses_zh'] = ','.join(accesses_zh)
        else:
            v_access = []
            active_spaces_zh = []
            if row['spaces']:
                for sp in row['spaces'].split(','):
                    v_access.append({
                        'name_space': sp,
                        'space_name': constant.VARIETY_SPACES.get(sp),
                        'expire': None,
                        'accessible': False
                    })
                    active_spaces_zh.append(constant.VARIETY_SPACES.get(sp))
            for ac in v_access:
                ac['variety_en'] = row['variety_en']
                if row['expire'] and ac['name_space'] == row['name_space']:
                    ac['expire'] = row['expire']
                    ac['accessible'] = row['expire'].strftime('%Y-%m-%d') >= today
                    if ac['accessible']:
                        accesses_zh.append(constant.VARIETY_SPACES.get(ac['name_space']))
            variety_data.append({
                'id': row['id'],
                'variety_name': row['variety_name'],
                'variety_en': row['variety_en'],
                'active_spaces': ','.join(active_spaces_zh),
                'group_name': row['group_name'],
                'exchange_name': row['exchange_name'],
                'accesses': v_access,
                'accesses_zh': ','.join(accesses_zh)
            })

    response_data = {
        'user': user_obj,
        'variety': variety_data,
        'space_all': [constant.VARIETY_SPACES.get(p['name_space'], p['name_space']) for p in spaces]
    }
    return AllResponse.operate_successfully(data=response_data)
